#include <iostream>
using std::cout;
using std::endl;
using std::ostream;


class Line
{
/* public: */
    class Point
    {
    public:
        Point(int x ,int y)
            : _ix(x)
              , _iy(y)
        {
            cout << "Point(int,int)" << endl;
        }

        Point(const Point & rhs)
            : _ix(rhs._ix)
              , _iy(rhs._iy)
        {
            cout << "Point(const Point &)" << endl;
        }


        void print(){
            cout << "(" << _ix
                << "," << _iy
                << ")";
        }

        void getLine(const Line & rhs){
            //以下的访问形式都ok
            //不需要添加任何额外的友元声明
            //在Point的成员函数中访问Line的私有的非静态成员
            rhs._pt1;
            //在Point的成员函数中访问Line的私有的静态成员
            rhs._line;
            Line::_line;
            //类似于全局类的成员函数中访问全局变量
            _line;
        }

        ~Point(){
            cout << "~Point()" << endl;
        }
        friend
        ostream & operator<<(ostream & os,const Line::Point & rhs);
        friend class Line;
    private:
        int _ix;
        int _iy;
        static int _iz;
    };
public:
    Line(int x1,int y1,int x2,int y2)
        : _pt1(x1,y1) 
          , _pt2(x2,y2)
    {
        cout << "Line(int*4)" << endl;
    }

    void printLine(){
        _pt1.print();
        cout << "------>";
        _pt2.print();
        cout << endl;
    }

    void getPoint(){
        //以下两种访问都需要在Point中声明友元
        //在Line的成员函数中访问Point的私有的普通成员
        /* _pt1._ix; */
        
        //在Line的成员函数中访问Point的私有的静态成员
        /* _pt1._iz; */
        /* Point::_iz; */

        //在Line中想要直接用数据成员名字访问Point的数据成员是不可能的
        /* _ix; */
    }

    ~Line(){
        cout << "~Line()" << endl;
    }

    friend
    ostream & operator<<(ostream & os,const Line & rhs);

    friend
    ostream & operator<<(ostream & os,const Point & rhs);
private:
    Point _pt1;
    Point _pt2;
    static int _line;
};
int Line::Point::_iz = 0;
int Line::_line = 1;

//为了用输出流运算符输出Line对象
//其中访问了Line的私有数据成员（_pt1,_pt2）
//所以要设为Line的友元
ostream & operator<<(ostream & os,const Line & rhs){
    os << rhs._pt1 << "----->" << rhs._pt2;
    return os;
}

//为了用输出流运算符输出Point对象
//其中访问了Point的私有数据成员(_ix,_iy)
//所以要设为Point的友元
//而且在形参中不能直接使用Point类型名称，需要加上Line的类名作用域
//
//如果Point是Line中的私有成员类型
//还需要将这个函数声明为Line的友元
ostream & operator<<(ostream & os,const Line::Point & rhs){
    os << "(" << rhs._ix << "," << rhs._iy << ")";
    return os;
}


void test0(){
    cout << sizeof(Line) << endl;
    Line ll(1,2,3,4);
    ll.printLine();

    /* Line::Point pt(1,2); */
}

void test1(){
    Line ll(1,2,3,4);
    cout << ll << endl;
}

int main(void){
    test1();
    return 0;
}
